//: C19:Urand.h
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 1999
// Copyright notice in Copyright.txt
// Unique random number generator
#ifndef URAND_H
#define URAND_H
#include <cstdlib>
#include <ctime>

template<int upperBound>
class Urand
{
    int used[upperBound];
    bool recycle;
public:
    Urand(bool recycle = false);
    int operator()(); // The "generator" function
};

template<int upperBound>
Urand<upperBound>::Urand(bool recyc)
        : recycle(recyc)
{
    memset(used, 0, upperBound * sizeof(int));
    srand(time(0)); // Seed random number generator
}

template<int upperBound>
int Urand<upperBound>::operator()()
{
    if (!memchr(used, 0, upperBound)) {
        if (recycle)
            memset(used,0,sizeof(used) * sizeof(int));
        else
            return -1; // No more spaces left
    }
    int newval;
    while (used[newval = rand() % upperBound])
        ; // Until unique value is found
    used[newval]++; // Set flag
    return newval;
}
#endif // URAND_H ///:~
